import os
import glob
import numpy as np
import pandas as pd

from pydub.audio_segment import AudioSegment
from scipy.io import wavfile
from python_speech_features import mfcc

class Data_Proccess:
    music_info_csv_file_path='../../doc/data/csv/music_info.csv'
    music_index_label_path='../../doc/data/csv/music_index_label.csv'
    music_features_file_path='../../doc/data/csv/music_features.csv'
    music_audio_dir='../../doc/data/music/mp3/*.mp3'
    wav_save_dir='../../doc/data/music/wav/'
    
    def extract_label(self):
        data=pd.read_csv(self.music_info_csv_file_path)
        data=data[['name','tag']]
        return data
    
    def fetch_index_label(self):
        #从文件中读取index和label之间的映射关系，并返回dict
        data=pd.read_csv(self.music_index_label_path,header=None,encoding='utf-8')
        name_label_list=np.array(data).tolist()
        index_label_dict=dict(map(lambda t:(t[1],t[0]),name_label_list))
        return index_label_dict
    
    def extract(self,old_file,new_file):
        items=old_file.split('.')
        file_format=items[-1].lower()
        #file_name=old_file[:-(len(file_format)+1)]
        if file_format !='wav':
            song=AudioSegment.from_file(old_file, format='mp3')
            song.export(new_file,format='wav')
        try:
            #file=file_name+'.wav'
            rate,data=wavfile.read(new_file)
            mfcc_feas=mfcc(data,rate,numcep=13,nfft=2048)
            mm=np.transpose(mfcc_feas)
            mf=np.mean(mm, axis=1)# mf变成104维的向量
            mc=np.cov(mm)
            result=mf
            for i in range(mm.shape[0]):
                result=np.append(result, np.diag(mc, i))
            os.remove(new_file)
            return result
        except Exception as msg:
            print(msg)
        
    def extract_and_export(self):
        df=self.extract_label()
        name_label_list=np.array(df)
        name_label_dict=dict(map(lambda t:(t[0],t[1]),name_label_list))
        labels=set(name_label_dict.values())
        label_index_dict=dict(zip(labels,np.arange(len(labels))))
        
        all_music_files=glob.glob(self.music_audio_dir)
        all_music_files.sort()
        
        loop_count=0
        flag=True
        
        all_mfcc=np.array([])
        for file_name in all_music_files:
            #print('开始处理：'+file_name.replace('\xa0',''))
            print('开始处理：'+file_name.replace('\\','/'))
            music_name=file_name.split('\\')[-1].split('.')[-2].split('-')[-1]
            music_name=music_name.strip()
            try:
                if music_name in name_label_dict:
                    label_index=label_index_dict[name_label_dict[music_name]]
                    new_file=self.wav_save_dir+music_name+'.wav'
                    ff=self.extract(file_name.replace('\\','/'),new_file)
                    ff=np.append(ff, label_index)

                    if flag:
                        all_mfcc=ff
                        flag=False
                    else:
                        all_mfcc=np.vstack([all_mfcc,ff])
                else:
                    #print('无法处理：'+file_name.replace('\xa0','')+'; 原因是：找不到对应的label')
                    print('无法处理：'+file_name.replace('\\','/')+'; 原因是：找不到对应的label') 
            except Exception as msg:
                print(msg)
                
            print('looping-----%d' % loop_count)
            print('all_mfcc.shape:',end='')
            print(all_mfcc.shape)
            loop_count+=1
            '''
           if loop_count>=10:
               break
           '''
        #保存数据
        label_index_list=[]
        for item in label_index_dict.items():
            label_index_list.append([item[0],item[1]])
        pd.DataFrame(label_index_list).to_csv(self.music_index_label_path,header=None,index=False,encoding='utf-8')
        pd.DataFrame(all_mfcc).to_csv(self.music_features_file_path,header=None,index=False,encoding='utf-8')
        
        return all_mfcc

